home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / dxcmds34.sit / Dartmouth XCMD's 3.4.3 / card_2946.txt < prev    next >
Text File  |  1990-04-17  |  39KB  |  1,287 lines

  1. -- card: 2946 from stack: in.3
  2. -- bmap block id: 6031
  3. -- flags: 4000
  4. -- background id: 8327
  5. -- name: XScrollBox
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XFCN,XScrollBox,it
  10.   InstallResource DITL,XScrollBox,it
  11.   InstallResource DLOG,XScrollBox,it
  12. end Install
  13.  
  14.  
  15. -- part 2 (field)
  16. -- low flags: 01
  17. -- high flags: 4007
  18. -- rect: left=384 top=58 right=286 bottom=491
  19. -- title width / last selected line: 0
  20. -- icon id / first selected line: 0 / 0
  21. -- text alignment: 0
  22. -- font id: 3
  23. -- text size: 9
  24. -- style flags: 0
  25. -- line height: 12
  26. -- part name: scroller
  27.  
  28.  
  29. -- part 3 (button)
  30. -- low flags: 00
  31. -- high flags: 8003
  32. -- rect: left=76 top=298 right=320 bottom=176
  33. -- title width / last selected line: 0
  34. -- icon id / first selected line: 0 / 0
  35. -- text alignment: 1
  36. -- font id: 0
  37. -- text size: 12
  38. -- style flags: 0
  39. -- line height: 16
  40. -- part name: XScrollBox
  41. ----- HyperTalk script -----
  42. on mouseUp
  43.   get XScrollBox("baker","Choose one of these:",card field "scroller","Help")
  44.   go this card
  45.   if it is "Help" then
  46.     answer "You pushed the 'Help' button."
  47.   else if it is "cancel" then
  48.     answer "You pushed the 'Cancel' button."
  49.   else if it is empty then
  50.     answer "You did not select anything."
  51.   else
  52.     answer "Your choice was: " & it
  53.   end if
  54. end mouseUp
  55.  
  56.  
  57.  
  58. -- part 5 (field)
  59. -- low flags: 01
  60. -- high flags: 2007
  61. -- rect: left=17 top=31 right=286 bottom=382
  62. -- title width / last selected line: 0
  63. -- icon id / first selected line: 0 / 0
  64. -- text alignment: 0
  65. -- font id: 3
  66. -- text size: 10
  67. -- style flags: 0
  68. -- line height: 13
  69. -- part name: Documentation
  70.  
  71.  
  72. -- part 7 (field)
  73. -- low flags: 81
  74. -- high flags: 0007
  75. -- rect: left=18 top=31 right=290 bottom=489
  76. -- title width / last selected line: 0
  77. -- icon id / first selected line: 0 / 0
  78. -- text alignment: 0
  79. -- font id: 3
  80. -- text size: 10
  81. -- style flags: 0
  82. -- line height: 13
  83. -- part name: Source1
  84.  
  85.  
  86. -- part 11 (field)
  87. -- low flags: 81
  88. -- high flags: 0007
  89. -- rect: left=18 top=31 right=290 bottom=489
  90. -- title width / last selected line: 0
  91. -- icon id / first selected line: 0 / 0
  92. -- text alignment: 0
  93. -- font id: 3
  94. -- text size: 10
  95. -- style flags: 0
  96. -- line height: 13
  97. -- part name: Source2
  98.  
  99.  
  100. -- part 12 (button)
  101. -- low flags: 00
  102. -- high flags: A003
  103. -- rect: left=289 top=298 right=320 bottom=458
  104. -- title width / last selected line: 0
  105. -- icon id / first selected line: 0 / 0
  106. -- text alignment: 1
  107. -- font id: 0
  108. -- text size: 12
  109. -- style flags: 0
  110. -- line height: 16
  111. -- part name: Show C Source: part 1
  112. ----- HyperTalk script -----
  113. on mouseUp
  114.   if the short name of me is "Show C Source: part 1" then
  115.     set the visible of card field "source1" to true
  116.     set the visible of card field "source2" to false
  117.     set the name of me to "Show C Source: part 2"
  118.   else if the short name of me is "Show C Source: part 2" then
  119.     set the visible of card field "source2" to true
  120.     set the visible of card field "source1" to false
  121.     set the name of me to "Hide C Source"
  122.   else
  123.     set the visible of card field "source2" to false
  124.     set the visible of card field "source1" to false
  125.     set the name of me to "Show C Source: part 1"
  126.   end if
  127. end mouseUp
  128.  
  129.  
  130.  
  131. -- part contents for card part 2
  132. ----- text -----
  133. able
  134. baker
  135. charlie
  136. dog
  137. ernest
  138. fox
  139. gamma
  140. horse
  141. ice cream
  142. jumping jack flash
  143. knockwurst
  144. liver
  145. monkey
  146. no way, jose
  147. occularity
  148. penelope
  149. qwerty
  150. rapscallion
  151. salubrious
  152. twinkle toes
  153. underwhelmed
  154. vermin
  155. wascally wabbit
  156. yokel
  157. zenzational
  158.  
  159. -- part contents for card part 5
  160. ----- text -----
  161. XScrollBox version 2.4
  162. Roger Brown
  163.  
  164. XScrollBox is a HyperCard XFCN that creates a scrolling selection dialog box from any multi-lined container.  Each line of the container is made into a selection line in the dialog. Only one line can be selected. 
  165.  
  166. The return value has two items: the number of the selection and the text of the selection. These are separated by commas as in normal HyperCard format. 
  167.    
  168. Selection can be made by :
  169.    1. double-clicking on a line.
  170.    2. single-clicking on a line, then pressing the OK button.
  171.    3. single-clicking on a line, then pressing the Return key.
  172.    4. typing the first letter(s) of a selection, then doing 1,2, or 3.
  173.      (Note: type selection assumes that the lines are ordered       
  174.        alphabetically)
  175.    5. scrolling with up and down arrow keys, then doing 1,2 or 3.
  176.    
  177.    If the Cancel button is pressed, the string "Cancel" is returned.
  178.    
  179.    It requires that the DITL and DLOG resources (1345) packaged  
  180.    with it are in the stack.
  181.    
  182.   The dialog is centered on the screen and sized to hold the width of the longest line and/or the prompt line, whichever is widest. It will not overrun the width of a  Mac+ screen.
  183.  
  184. INVOKING XScrollBox
  185.  
  186.   get XScrollBox(first,prompt,container,userButton)
  187.         
  188.    where   first  is a default selection in the list - either a number or                   
  189.                           a  text string (0 if none).
  190.                 prompt is a string to prompt the user. This appears at the 
  191.                           top of the dialog box.
  192.                 container is any hypercard container (field, variable), 
  193.                            presumed to be multi-lined.
  194.                 UserButton  is the name for an optional author specified 
  195.                            button. If this button is pressed, its name is 
  196.                            returned further processing by the script.  
  197.                    
  198.  
  199. EXAMPLE
  200.  
  201.  ex.  get XScrollBox(1,"Choose:",card field 1,"Help")
  202.         if OK is pressed, returns : 1,text of line 1 of card field 1
  203.  
  204.  
  205. REVISION HISTORY
  206. 1.1 center dialog box on any size screen
  207. 1.2 - add selection scrolling by typing and by cursor keys
  208. 1.3 - add text of chosen item to return value
  209. 1.4 - 3/2/88   add optional user button
  210. 1.6 - 5/12/89  fixed problem with selecting the first item the 
  211.           first time when type-selecting.  Fixed problem where typing 
  212.           an item exactly selects the one after it.
  213. 1.7 - 5/15/89 made it compile under LSC 3.0.
  214. 2.0 - 9/9/89 SuperCard compatible, fixed bugs in typing-selection,
  215.          and userButton string handling.  First item is selected if there     
  216.          is no default and the user presses a cursor arrow key. One 
  217.          source for all 3 versions, control version with compiler 
  218.          variables. Compiles under THINK C Γäó 4.0.
  219. 2.1 - 2/21/90 Push of cancel button now returns "Cancel" string.
  220.          Fixed some bugs in allocatin and use of return handle.
  221. 2.2 - 3/29/90 Correctly displays eight-bit characters.
  222. 2.3 - 3/30/90 added ScrollBoxML variation
  223. 2.4 - 4/17/90 revived a feature that had disappeared: specifying    
  224.           the default selection in XScrollBox and XScrollBox F as a 
  225.           string rather than a number
  226.  
  227.  
  228. -- part contents for card part 7
  229. ----- text -----
  230. /* XScrollBox2.3.c */
  231. /* ┬⌐ Digital Medicine Inc. 1988 */
  232. /* written in THINK CΓäó Version 4.0  ┬⌐ Think Technologies, Inc */
  233. /* version 2.0 by Roger Brown 9/9/88  Dartmouth Courseware Development Group */
  234.  
  235. /* version 2.3: 3/30/90 Added special request version XScrollBoxML that delimits 
  236.    chosen items by carriage return rather than by line so that items can have 
  237.    commas in them.
  238. /* version 2.2: 3/29/90 Control character filter applied to the text in
  239.    SetUpScrollBox was also filtering out 8 bit characters.  Fixed by
  240.    casting the character to a Byte before testing for < 31.
  241. /* version 2.1: 2/21/90 if the cancel button is pressed, the word "Cancel" is returned
  242.    so we can distinguish between that and pressing OK with no selection made. Also
  243.    fixed some bugs in allocation and use of ResultHandle global. */
  244. /* version 2 is a major source code change to include all three versions 
  245.    (XScrollBox, XScrollBoxM, and XScrollBoxF) in the same source file with
  246.    compiler directives to distinguish them. 
  247.    
  248.    To compile verson                    set flags
  249.    ------------------                   --------------------
  250.    XScrollBox                           #define VERSION XScrollBox
  251.    XScrollBox (Multiple Selection, 
  252.                item formatted return)   #define VERSION XScrollBoxM
  253.    XScrollBox (Multiple Selection, 
  254.                line formatted return)   #define VERSION XScrollBoxML
  255.    XScrollBox (list in special font)    #define VERSION XScrollBoxF
  256.   
  257.  */
  258.    
  259. /* This is a HyperCard XFCN that creates a scrolling selection dialog box from
  260.    any multi-lined container. Syntax is:
  261.    
  262.    XScrollBox version:
  263.    -------------------
  264.    
  265.         get XScrollBox(first,prompt,container,userButton)
  266.    
  267.    ex.      get XScrollBox(1,"Choose:",card field 1,"Help")
  268.   
  269.    returns: 1,text of line 1 of card field 1
  270.    
  271.    where    first       is a default selection in the list - either a number
  272.                         or a text string (0 if none).
  273.             prompt      is a string to prompt the user. This appears at the
  274.                         top of the dialog box.
  275.             container   is any hypercard container (field, variable), presumed to be 
  276.                         multi-lined.
  277.             UserButton  is the name for an optional author specified button.
  278.                         If this button is pressed, its name is returned
  279.                         for further processing by the script.  
  280.                     
  281.    Each line of the container is made into a selection line in the
  282.    dialog. Only one line can be selected. 
  283.    
  284.    The return value has two items: the number of the selection and the text of
  285.    the selection. These are separated by commas as in normal HyperCard format. 
  286.    
  287.    Selection can be made by:
  288.    
  289.    1. double-clicking on a line.
  290.    2. single-clicking on a line, then pressing the OK button.
  291.    3. single-clicking on a line, then pressing the Return key.
  292.    4. typing the first letter(s) of a selection, then doing 1,2, or 3.
  293.       (Note: type selection assumes that the lines are ordered alphabetically)
  294.    5. scrolling with up and down arrow keys, then doing 1,2 or 3.
  295.    
  296.    The dialog box is centered in the card window.
  297.    If the Cancel button or command-period is pressed, a null string is returned.
  298.    It requires that the DITL and DLOG resources 1345, packaged with it are 
  299.    in the stack.
  300.    
  301.    To compile: create a project with this, ANSI-A4 and MacTraps. Build as code 
  302.    resource type XFCN, ID 1345, name XScrollBox.
  303.    
  304.    XScrollBoxF version:
  305.    --------------------
  306.    
  307.    You can specify a special font in which to display the list.
  308.    
  309.             get XScrollBoxF(first,prompt,container,userButton,font)
  310.    
  311.    ex.      get XScrollBoxF(1,"Choose:",card field 1,"Help",courier)
  312.   
  313.    returns: 1,text of line 1 of card field 1
  314.    
  315.    where    first       is a default selection in the list - either a number
  316.                         or a text string (0 if none).
  317.             prompt      is a string to prompt the user. This appears at the
  318.                         top of the dialog box.
  319.             container   is any hypercard container (field, variable), presumed to be 
  320.                         multi-lined.
  321.             UserButton  is the name for an optional author specified button.
  322.                         If this button is pressed, its name is returned
  323.                         for further processing by the script.  
  324.             font        is an optional font to display the list in.
  325.    
  326.    It requires that the DITL and DLOG resources 1347, packaged with it are 
  327.    in the stack.
  328.                   
  329.    To compile: create a project with this, ANSI-A4, and MacTraps. Build as 
  330.    code resource type XFCN, ID 1347, name XScrollBoxF.
  331.  
  332.    
  333.    XScrollBoxM version:
  334.    -------------------
  335.   
  336.    Like XScrollBox except that it allows multiple selections.
  337.    
  338.             get XScrollBoxM(first,prompt,container,userButton)
  339.    
  340.    ex.      get XScrollBoxM("1,3,5","Choose:",card field 1,"Help")
  341.   
  342.    returns: 1,text of line 1 of card field 1,3,text of line 3 of card field 1,
  343.             5,text of line 5 of card field 1
  344.    
  345.    where    first       is a list of 1 or more default selections in the list - 
  346.                         either numbers or an item list of text strings (0 if none).
  347.                         NOTE: the text must exactly match what is in the field!
  348.             prompt      is a string to prompt the user. This appears at the
  349.                         top of the dialog box.
  350.             container   is any hypercard container (field, variable), presumed to be 
  351.                         multi-lined.
  352.             UserButton  is the name for an optional author specified button.
  353.                         If this button is pressed, its name is returned
  354.                         for further processing by the script.  
  355.                 
  356.    Each line of the container is made into a selection line in the
  357.    dialog. Multiple lines can be selected. 
  358.    
  359.    The return value is an item list in the format:
  360.         
  361.         number,text,number,text,..number,text
  362.         
  363.         where number is the number of a selection 
  364.               text is the text of the selection with that number
  365.   
  366.    It requires that the DITL and DLOG resources 1346, packaged with it are 
  367.    in the stack.
  368.                   
  369.    To compile: create a project with this, ANSI-A4, and MacTraps. Build as 
  370.    code resource type XFCN, ID 1346, name XScrollBoxM.
  371.  
  372.    XScrollBoxML version:
  373.    -------------------
  374.   
  375.    Like XScrollBoxM except that the return result has one line per item chosen.
  376.    This makes it easier to handle selection items that have embedded commas.
  377.    
  378.             get XScrollBoxML(first,prompt,container,userButton)
  379.    
  380.    ex.      get XScrollBoxML("1,3,5","Choose:",card field 1,"Help")
  381.   
  382.    returns: 1,text of line 1 of card field 1 <CR>
  383.             3,text of line 3 of card field 1 <CR>
  384.             5,text of line 5 of card field 1
  385.    
  386.    where    first       is a list of 1 or more default selections in the list - 
  387.                         either numbers or an item list of text strings (0 if none).
  388.                         NOTE: the text must exactly match what is in the field!
  389.             prompt      is a string to prompt the user. This appears at the
  390.                         top of the dialog box.
  391.             container   is any hypercard container (field, variable), presumed to be 
  392.                         multi-lined.
  393.             UserButton  is the name for an optional author specified button.
  394.                         If this button is pressed, its name is returned
  395.                         for further processing by the script.  
  396.                 
  397.    Each line of the container is made into a selection line in the
  398.    dialog. Multiple lines can be selected. 
  399.    
  400.    The return value is an item list in the format:
  401.         
  402.         number,text <CR>
  403.         number,text <CR>
  404.         .. <CR>
  405.         number,text
  406.         
  407.         where number is the number of a selection 
  408.               text is the text of the selection with that number
  409.   
  410.    It requires that the DITL and DLOG resources 1348, packaged with it are 
  411.    in the stack.
  412.                   
  413.    To compile: create a project with this, ANSI-A4, and MacTraps. Build as 
  414.    code resource type XFCN, ID 1348, name XScrollBoxML.
  415.  
  416. */
  417.  
  418.  
  419.  
  420. #include "QuickDraw.h"
  421. #include "EventMgr.h"
  422. #include "WindowMgr.h"
  423. #include "ResourceMgr.h"
  424. #include "ControlMgr.h"
  425. #include "DialogMgr.h"
  426. #include "ListMgr.h"
  427. #include "ToolboxUtil.h"
  428. #include "HyperXCmd.h"
  429. #include "XCmdGlue.inc.c"
  430. #include "SetUpA4.h"
  431.  
  432. #define XScrollBox   1
  433. #define XScrollBoxM  2
  434. #define XScrollBoxF  3
  435. #define XScrollBoxML  4
  436.  
  437.  
  438. /* specify verson here */
  439.  
  440. #define VERSION  XScrollBox
  441.  
  442. /* utility definitions */
  443.  
  444. #define FALSE 0
  445. #define TRUE !FALSE
  446. #define NULL 0L
  447.  
  448. /* globals */
  449.  
  450. #define kOKbutton 1
  451. #define kCancel 2
  452. #define kPrompt 3
  453. #define kListItem 4
  454. #define kOutliner 5
  455. #define kUserButton 6
  456. #define kTyping 99
  457.  
  458. #define kCancelString "Cancel"
  459.  
  460. int kScrollBarWidth = 15;
  461.  
  462. int kStdLDEF = 0;
  463.  
  464. #if VERSION == XScrollBox
  465.     int kDialogId = 1345;
  466.     int kStringListId = 1345;
  467. #endif
  468.  
  469. #if VERSION == XScrollBoxM
  470.     int kDialogId = 1346;
  471.     int kStringListId = 1346;
  472. #endif
  473.  
  474. #if VERSION == XScrollBoxF
  475.     int kDialogId = 1347;
  476.     int kStringListId = 1347;    
  477.     Str255 gPrompt,fontName;
  478. #endif
  479.  
  480. #if VERSION == XScrollBoxML
  481.     int kDialogId = 1348;
  482.     int kStringListId = 1348;
  483. #endif
  484.  
  485. int gCellWidth;
  486. int gCellHeight = 16;
  487.  
  488. Rect dialogRect,listRect,cardRect;
  489. ListHandle theList;
  490. DialogPtr theListDialog;
  491. Str255 theResult,userButton;
  492. long theStartWith;
  493. Str255 startString;
  494. char startIsString;
  495. Handle resultHandle;
  496. CursHandle theCursor;
  497. char collector[32];
  498. int charPos;
  499. long charTime;
  500. Handle startHandle;
  501. int theModifiers;
  502.  
  503. XCmdBlockPtr gParamPtr;
  504.  
  505. /* return max of 2 integers */
  506.  
  507. max(a,b)
  508. int a,b;
  509.     if (a>b) return a;
  510.     return b;
  511. }
  512.  
  513. /* return min of 2 integers */
  514.  
  515. min(a,b)
  516. {
  517.     if (a<b) return a;
  518.     return b;
  519. }
  520.  
  521. #if (VERSION == XScrollBoxM) || (VERSION == XScrollBoxML)
  522.  
  523.     /* Get HyperCard comma delimited item i from item list string s. */
  524.     
  525.     GetHCItem(inStr,i,outStr)
  526.     char *inStr,*outStr;
  527.     int i;
  528.     /* Get HyperCard comma delimited item i from item list string inStr. Return it in outStr */
  529.     {
  530.         int c,len,count,j;
  531.         char temp[32];
  532.         
  533.         count = j = 0;
  534.         len = strlen(inStr);
  535.         for (c=0;c<len;c++) {
  536.             if (inStr[c]==',') {
  537.                 count = count + 1;
  538.                 if (count==i) break;
  539.                 j = 0;
  540.             }
  541.             else {
  542.                 temp[j] = inStr[c];
  543.                 j++;
  544.                 if (c==(len-1)) { /* last item, no comma */
  545.                     count = count+1;
  546.                     break;
  547.                 }
  548.             }
  549.         }
  550.         if (count < i) strcpy(temp,"");  /* no item there */
  551.         temp[j] = 0;
  552.         strcpy(outStr,temp);
  553.         return;
  554.     }
  555. #endif
  556.  
  557. /* Get the coordiates of the HyperCard card window so we can center the dialog in it. */
  558.  
  559. GetCardRect(itsRect)
  560. Rect *itsRect;
  561. {
  562.     WindowPtr cardWindow;
  563.     Rect r;
  564.     Point thePt;
  565.         
  566.     GetPort(&cardWindow);
  567.     r = (*cardWindow).portRect;
  568.     SetPt(&thePt,0,0);
  569.     LocalToGlobal(&thePt);
  570.     OffsetRect(&r,thePt.h,thePt.v);
  571.     *itsRect = r;
  572. }
  573.  
  574. /* user item in dialog box to outline the default (ok) button */
  575.  
  576. pascal void OutlineButton (myWindow,itemNo)
  577. WindowPtr myWindow;
  578. int itemNo;
  579. {
  580.     int iType;
  581.     Handle iHandle;
  582.     Rect iBox;
  583.     
  584.     SetUpA4();
  585.     GetDItem(theListDialog, kOKbutton, &iType, &iHandle, &iBox);
  586.     InsetRect(&iBox, -4, -4);
  587.     PenSize(3, 3);
  588.     FrameRoundRect(&iBox, 16, 16);
  589.     PenNormal();
  590.     RestoreA4();
  591. }
  592.  
  593. /* User item in dialog box to display the selection list */
  594.  
  595. pascal void DrawListItem (myWindow,itemNo)
  596. WindowPtr myWindow;
  597. int itemNo;
  598. /* draw the selection list */
  599. {
  600.     RgnHandle theRgn;
  601.     Rect listFrame;
  602.     
  603.     SetUpA4();
  604.     listFrame = (**theList).rView;
  605.     InsetRect(&listFrame, -1, -1);
  606.     FrameRect(&listFrame);
  607.     theRgn = NewRgn();
  608.     RectRgn(theRgn, &(*theListDialog).portRect);
  609.     LUpdate(theRgn, theList);
  610.     DisposeRgn(theRgn);
  611.     RestoreA4();
  612. }
  613.  
  614. /* change a string to all upper case */
  615.  
  616. ucase(s)
  617. char *s;
  618. {
  619.     int i;
  620.     char c;
  621.     
  622.     for (i=0;i<strlen(s);i++) {
  623.         s[i] = toupper(s[i]);
  624.     }
  625. }
  626.  
  627. /* string selection logic for selection via typed characters */
  628.  
  629. pascal int MySelect(aPtr,bPtr,aLen,bLen)
  630. Ptr aPtr,bPtr;int aLen,bLen;
  631. {
  632.     /* return 0 if string a >= string b, else return 1 */
  633.     
  634.     Str255 a,b;
  635.     int i,compare;
  636.     
  637.     SetUpA4();
  638.     for (i=0;i<aLen;i++) 
  639.         a[i] = toupper(*(aPtr+i));
  640.     a[aLen] = 0;
  641.     for (i=0;i<bLen;i++) 
  642.         b[i] = toupper(*(bPtr+i));
  643.     b[bLen] = 0;
  644.     compare = strcmp(a,b);
  645.     RestoreA4();
  646.     if (compare < 0) return 1;
  647.     return 0;
  648. }
  649.  
  650. /* scroll selection list up or down */
  651.  
  652. VerticalScroll(c)
  653. char c;
  654. {
  655.     Cell oldCell,aCell;
  656.         
  657.     SetUpA4();
  658.     SetPt(&oldCell,0,0);
  659.     if (!LGetSelect(TRUE,&oldCell,theList)) {  /* get current selection */
  660.         SetPt(&oldCell,1,-1);
  661.     }
  662.     if (c==30) {
  663.         SetPt(&aCell,0,max(0,oldCell.v-1));
  664.     }
  665.     else if (c==31) {
  666.         SetPt(&aCell,0,min((**theList).dataBounds.bottom-1,oldCell.v+1));
  667.     }
  668.     if (EqualPt(oldCell,aCell)==1) {
  669.         SysBeep(0);
  670.         RestoreA4();
  671.         return;
  672.     }
  673.     LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  674.     LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  675.     LAutoScroll(theList);
  676.     RestoreA4();
  677. }
  678.  
  679. /* Select by typing - a filter proc for ModalDialog. Simulates SFGetFile dialog action. */
  680.  
  681. pascal char NameSelect(theDialog,theEvent,itemHit)
  682. DialogPtr theDialog;EventRecord *theEvent;int *itemHit;
  683. {
  684.     int c;
  685.     long dummy;
  686.     int iType;
  687.     Handle iHandle;
  688.     Rect iBox;
  689.     char result,theChar;
  690.     
  691.     SetUpA4();
  692.     result = FALSE;
  693.     theModifiers = theEvent->modifiers;
  694.     if ((theEvent->what == keyDown)||(theEvent->what == autoKey)) {
  695.         theChar = BitAnd(theEvent->message,charCodeMask);
  696.         if (TickCount() > charTime) charPos = 0;
  697.         if (BitAnd(theEvent->modifiers,cmdKey)) { /* command key is down */
  698.             if (theChar==46) {  /* command-period */
  699.                 *itemHit = 2;
  700.                 GetDItem(theListDialog,kCancel,&iType,&iHandle,&iBox);
  701.                 HiliteControl(iHandle,inButton);
  702.                 result = TRUE;
  703.             }
  704.         }
  705.         else {
  706.             collector[charPos] = theChar;
  707.             if ((collector[charPos] ==13)||(collector[charPos]==3)) {  
  708.                 /* is CR, use as normal */
  709.                 *itemHit = 1;
  710.                 GetDItem(theListDialog, kOKbutton, &iType, &iHandle, &iBox);
  711.                 HiliteControl(iHandle,inButton);
  712.                 result = TRUE;
  713.             }
  714.             else if ((collector[charPos]==31)||(collector[charPos]==30)) {  
  715.                 /* cursor up/down */
  716.                 VerticalScroll(collector[charPos]);
  717.                 charPos = 0;
  718.             }
  719.             else {
  720.                 charPos++;
  721.                 collector[charPos] = 0;
  722.                 *itemHit = kTyping;
  723.                 result = TRUE;
  724.                 charTime = TickCount()+45; 
  725.             }
  726.         }
  727.     }
  728.     RestoreA4();
  729.     return result;
  730. }
  731.  
  732. #if (VERSION == XScrollBoxM) || (VERSION == XScrollBoxML)
  733.  
  734.     /* set up defaults */
  735.     
  736.     SetInitialSelections(maxLines)
  737.     /* select anything in the starthandle */
  738.     int maxLines;
  739.     {
  740.         int i,j;
  741.         Str255 nextItem;
  742.         Cell aCell,oldCell;
  743.         char startIsString;
  744.         long num;
  745.         
  746.         i = 1;
  747.         GetHCItem(*startHandle,i,nextItem);
  748.         if (strlen(nextItem)==0) return;          /* no initial selections */
  749.         
  750.         /* is the first one a string or a number? */
  751.         
  752.         startIsString = TRUE;
  753.         for (j=0;j<strlen(nextItem);j++) {
  754.             if (!isalpha(nextItem[j])) {
  755.                 startIsString = FALSE;
  756.                 break;
  757.             }
  758.         }
  759.         if (startIsString) {          /* set up initial selections as strings */
  760.             SetPt(&aCell,0,0);
  761.             while (LSearch(nextItem,strlen(nextItem),NULL,&aCell,theList)) {
  762.                 LSetSelect(TRUE,aCell,theList);     /* set the first one */   
  763.                 LAutoScroll(theList);
  764.                 i++;
  765.                 GetHCItem(*startHandle,i,nextItem);
  766.                 SetPt(&aCell,0,0);
  767.                 if (strlen(nextItem)==0) return;     /* null string ends it */
  768.             }
  769.         }
  770.         else {   
  771.             while (strlen(nextItem)>0) {
  772.                 CtoPstr((char *)nextItem);                       /* process a list of numbers */
  773.                 StringToNum(nextItem,&num);
  774.                 if ((num > 0)&&(num<maxLines)); {
  775.                     SetPt(&aCell, 0,(int)num-1);
  776.                     LSetSelect(TRUE, aCell, theList);
  777.                     if (i==1) LAutoScroll(theList);
  778.                 }
  779.                 i++;
  780.                 GetHCItem(*startHandle,i,nextItem);
  781.             }
  782.         }
  783. }
  784. #endif
  785.  
  786. #if VERSION == XScrollBoxF
  787.  
  788.     /* user item to draw the prompt in the system font */
  789.     
  790.     pascal void DrawPrompt(myWindow,itemNo)
  791.     WindowPtr myWindow;
  792.     int itemNo;
  793.     {
  794.         int saveFont;
  795.         int iType;
  796.         Handle iHandle;
  797.         Rect iBox;
  798.         
  799.         SetUpA4();
  800.         GetDItem(theListDialog, kPrompt, &iType, &iHandle, &iBox);
  801.         
  802.         saveFont = myWindow->txFont;
  803.         myWindow->txFont = systemFont;
  804.         MoveTo(iBox.left+2,iBox.bottom-4);
  805.         CtoPstr((char*)gPrompt);
  806.         DrawString(gPrompt);
  807.         myWindow->txFont = saveFont;
  808.         RestoreA4();
  809.     }
  810. #endif
  811.  
  812. /* Create, size, center, and fill in the selection box. Returns 0 if any errors occur. */
  813.  
  814. int SetupScrollBox (prompt,theField)
  815. char *prompt;
  816. char *theField;
  817. {
  818.     Rect dataBounds, itemBox,tempRect;
  819.     char doVScroll, doHScroll;
  820.     Point cellSize;
  821.     Cell aCell,oldCell;
  822.     int i,j, itemType,x,y;
  823.     ControlHandle itemHandle;
  824.     Str255 aString;
  825.     long len;
  826.     int fieldLen;
  827.     int numLines,lineLen,maxLen,row;
  828.     char done,c;
  829.     int screenCenterX,screenCenterY;
  830.     int dialogWidth;
  831.     int dialogCenterX,dialogCenterY;
  832.     int itemWidth,itemHeight;
  833.     int itemHit;
  834.     GrafPtr gp;
  835.     Handle tempHandle;
  836.     int numButtons,cWidth;
  837.     
  838.     #if VERSION == XScrollBoxF
  839.         int theFont;
  840.         strcpy(gPrompt,prompt);
  841.     #endif
  842.     
  843.     if (strlen(userButton)>0) numButtons = 3;
  844.     else numButtons = 2;
  845.     
  846.     cWidth = CharWidth('m');
  847.     /* size the dialog box */
  848.     
  849.     dialogWidth = 200+cWidth*strlen(userButton); 
  850.             /* minimum width to fit buttons at bottom */
  851.             /* make sure the prompt fits */
  852.     dialogWidth = max(dialogWidth,strlen(prompt)*cWidth+20);
  853.         
  854.     /* find the longest line */
  855.     
  856.     lineLen = maxLen = numLines = 0;
  857.     fieldLen = strlen(theField);
  858.     for (i=0;i<fieldLen;i++) {
  859.         c = theField[i];
  860.         if ((c ==13)||(i==(fieldLen-1))) {
  861.             maxLen = max(lineLen,maxLen);
  862.             lineLen = 0;
  863.             numLines++;
  864.         }
  865.         else lineLen++;
  866.     }
  867.     gCellWidth = maxLen*cWidth;
  868.     
  869.     /* size it to have 10 lines visible and cWidth pixels per character */
  870.     /* leave room at the top for the prompt and at the bottom for
  871.        the OK button */
  872.        
  873.     dialogWidth = max(dialogWidth,gCellWidth+20+16);
  874.     dialogWidth = min(dialogWidth,490);  /* chop to screen width */
  875.     
  876.     gCellWidth = dialogWidth-20-16;
  877.     
  878.     SetRect(&dialogRect,0,0,dialogWidth,75+(10*gCellHeight));
  879.     SetRect(&listRect,10,30,10+gCellWidth,30+(10*gCellHeight));
  880.     
  881.     /* now center it in the current port */
  882.         
  883.     screenCenterX = cardRect.left + (cardRect.right - cardRect.left)/2;
  884.     screenCenterY = cardRect.top + (cardRect.bottom - cardRect.top)/2;
  885.  
  886.     dialogCenterX = dialogRect.left + (dialogRect.right-dialogRect.left)/2;
  887.     dialogCenterY = dialogRect.top + (dialogRect.bottom-dialogRect.top)/2;
  888.             
  889.     OffsetRect(&dialogRect,screenCenterX-dialogCenterX,
  890.                 screenCenterY-dialogCenterY);
  891.     
  892.     dialogCenterX = dialogRect.left + (dialogRect.right-dialogRect.left)/2;
  893.     dialogCenterY = dialogRect.top + (dialogRect.bottom-dialogRect.top)/2;
  894.     
  895.     /* now get the dialog resource */
  896.     
  897.     tempHandle = GetResource('DLOG',kDialogId);
  898.     if (tempHandle==NULL) {
  899.         return 0;
  900.     }
  901.     
  902.     theListDialog = GetNewDialog(kDialogId, NULL,(WindowPtr)NULL);
  903.  
  904.     
  905.     /* size it and center it */
  906.     
  907.     MoveWindow(theListDialog,dialogRect.left,dialogRect.top,FALSE);
  908.     SizeWindow(theListDialog,dialogRect.right-dialogRect.left,
  909.                 dialogRect.bottom-dialogRect.top,FALSE);
  910.     
  911.     /* adjust the ok button */
  912.     
  913.     GetDItem(theListDialog,kOKbutton,&itemType,&itemHandle,&itemBox);
  914.     itemWidth = (itemBox.right-itemBox.left);
  915.     itemHeight = (itemBox.bottom-itemBox.top);
  916.     x = listRect.left  + 
  917.         (listRect.right+16-listRect.left)/(numButtons*2) - itemWidth/2;
  918.     y = listRect.bottom + 15;   
  919.     SetRect(&itemBox,x,y,x+itemWidth,y+itemHeight); 
  920.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  921.     SetDItem(theListDialog,kOKbutton,itemType,itemHandle,&itemBox);
  922.     
  923.         
  924.     /* adjust the cancel button */
  925.     
  926.     GetDItem(theListDialog,kCancel,&itemType,&itemHandle,&itemBox);
  927.     itemWidth = (itemBox.right-itemBox.left);
  928.     itemHeight = (itemBox.bottom-itemBox.top);
  929.     x = listRect.left  + 
  930.         (numButtons*2-1)*(listRect.right+16-listRect.left)/(numButtons*2)
  931.          - itemWidth/2;
  932.     y = listRect.bottom + 15;   
  933.     SetRect(&itemBox,x,y,x+itemWidth+100,y+itemHeight); 
  934.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  935.     SetDItem(theListDialog,kCancel,itemType,itemHandle,&itemBox);
  936.     
  937.     /* set up the user button if there is one */
  938.         
  939.     GetDItem(theListDialog,kUserButton,&itemType,&itemHandle,&itemBox);
  940.     CtoPstr((char *)userButton);
  941.     SetCTitle(itemHandle,userButton);
  942.     itemHeight = (itemBox.bottom-itemBox.top);
  943.     PtoCstr((char*)userButton);
  944.     itemWidth = cWidth*strlen(userButton);
  945.     x = listRect.left  + 
  946.         (numButtons*(listRect.right+16-listRect.left)/(numButtons*2))
  947.         - itemWidth/2;
  948.     x = x + 2;        /* to balance OK button outliner */
  949.     y = listRect.bottom + 15;
  950.     SetRect(&itemBox,x,y,x+itemWidth,y+itemHeight);
  951.     MoveControl(itemHandle,itemBox.left,itemBox.top);
  952.     SizeControl(itemHandle,itemWidth,itemHeight);
  953.     SetDItem(theListDialog,kUserButton,itemType,itemHandle,&itemBox);
  954.     
  955.     
  956.     /* adjust the prompt string and fill it in */
  957.     
  958.     GetDItem(theListDialog,kPrompt,&itemType,&itemHandle,&itemBox);
  959.     itemWidth = strlen(prompt)*cWidth;
  960.     CtoPstr((char *)prompt);    
  961.     SetIText(itemHandle,prompt);
  962.     itemHeight = (itemBox.bottom-itemBox.top);
  963.     x = listRect.left  + 
  964.         (listRect.right+16 - listRect.left)/2 - itemWidth/2;
  965.     y = listRect.top - 5;   
  966.     SetRect(&itemBox,x,y-itemHeight,x+itemWidth,y);     
  967.     
  968.     #if VERSION == XScrollBoxF
  969.         /* now install a userproc to display the prompt in system font */
  970.         
  971.         SetDItem(theListDialog,kPrompt,userItem,DrawPrompt,&itemBox);
  972.     #else
  973.         SetDItem(theListDialog,kPrompt,itemType,itemHandle,&itemBox);
  974.     #endif
  975.     
  976.     /* now create the text list */
  977.     
  978.     SetRect(&dataBounds, 0, 0, 1, numLines);
  979.     SetPt(&cellSize, gCellWidth, gCellHeight);
  980.     theList = LNew(&listRect, &dataBounds, cellSize,
  981.          kStdLDEF, (WindowPtr)theListDialog, FALSE, FALSE, FALSE, TRUE);
  982.          
  983.     #if (VERSION != XScrollBoxM) && (VERSION != XScrollBoxML)
  984.         (**theList).selFlags = lOnlyOne;
  985.     #else 
  986.         (**theList).selFlags = lNoRect+lNoExtend+lUseSense;
  987.     #endif
  988.  
  989.     /* now fill in its text */
  990.     /* squeeze out control characters 2/27/88 */
  991.     
  992.     j = 0;row = 0;
  993.     for (i=0;i<fieldLen;i++) {
  994.         if ((Byte)theField[i] > 31) {
  995.             aString[j] = theField[i];
  996.             j++;
  997.         }
  998.         if ((theField[i] ==13)||(i==(fieldLen-1))) {
  999.             aString[j] = 0;
  1000.             SetPt(&aCell,0,row);
  1001.             row ++;
  1002.             lineLen = strlen(aString);
  1003.             LSetCell(&aString[0], lineLen, aCell, theList);
  1004.             j = 0;
  1005.         } 
  1006.     }
  1007.     #if (VERSION == XScrollBoxM) || (VERSION == XScrollBoxML)
  1008.         SetInitialSelections(numLines);
  1009.     #else
  1010.     
  1011.         if (startIsString) {
  1012.             SetPt(&oldCell,0,0);
  1013.             LGetSelect(TRUE,&oldCell,theList);  /* get current selection */
  1014.             SetPt(&aCell,0,0);
  1015.             if (LSearch(startString,strlen(startString),MySelect,&aCell,theList)) {
  1016.                 if (!EqualPt(oldCell,aCell)) {
  1017.                     LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  1018.                     LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  1019.                     LAutoScroll(theList);
  1020.                 }
  1021.             }
  1022.         }
  1023.         else if ((theStartWith > 0)&&(theStartWith<numLines)); {
  1024.             SetPt(&aCell, 0,theStartWith-1);
  1025.             LSetSelect(TRUE, aCell, theList);
  1026.             if (theStartWith>10) LAutoScroll(theList);
  1027.         }
  1028.     #endif
  1029.     LDoDraw(TRUE, theList);
  1030.     
  1031.     
  1032.     /* now complete the two user items of the dialog */
  1033.     
  1034.     itemBox = listRect;
  1035.     itemBox.right = itemBox.right + kScrollBarWidth;
  1036.  
  1037.     SetDItem(theListDialog, kListItem, userItem, DrawListItem, &itemBox);
  1038.     GetDItem(theListDialog,kOKbutton,&itemType,&itemHandle,&itemBox);
  1039.     SetDItem(theListDialog, kOutliner, userItem + itemDisable, OutlineButton, &itemBox);
  1040.     
  1041.     #if VERSION == XScrollBoxF
  1042.         /* install the font */
  1043.         
  1044.         if (strlen(fontName) > 0) {
  1045.             CtoPstr((char*)fontName);
  1046.             GetFNum(fontName,&theFont);
  1047.              if (theFont>0) 
  1048.                 theListDialog->txFont = theFont;
  1049.         }
  1050.     #endif
  1051.     
  1052.     /* present the window up front */
  1053.     
  1054.     ShowWindow(theListDialog);
  1055.     BringToFront(theListDialog);
  1056.  
  1057.     return 1;
  1058. }
  1059.  
  1060.  
  1061. -- part contents for card part 11
  1062. ----- text -----
  1063. DoListDialog ()
  1064.  
  1065. /* pose the dialog and handle it */
  1066.  
  1067. {
  1068.     int itemHit;
  1069.     Point aPoint;
  1070.     Cell oldCell,aCell;
  1071.     Boolean somethingSelected,found;
  1072.     Str255 temp;
  1073.     
  1074.     itemHit = charPos = 0;
  1075.     while (1) {
  1076.         RememberA4();
  1077.         ModalDialog(NameSelect, &itemHit);
  1078.         switch (itemHit) {
  1079.             case kOKbutton :
  1080.                 return 1;
  1081.             break;
  1082.             case kCancel:
  1083.                 return -1;
  1084.             break;
  1085.             case kListItem:
  1086.                 SetPort(theListDialog);
  1087.                 GetMouse(&aPoint);
  1088.                 if (LClick(aPoint, theModifiers, theList)) return 1;
  1089.             break;
  1090.             case kUserButton:
  1091.                 return 2;
  1092.             break;
  1093.             case kTyping:
  1094.                 SetPt(&oldCell,0,0);
  1095.                 /* get current selection */
  1096.                 somethingSelected = LGetSelect(TRUE,&oldCell,theList); 
  1097.                 SetPt(&aCell,0,0);
  1098.                 RememberA4();
  1099.                 found = LSearch(collector,strlen(collector),MySelect,&aCell,theList);
  1100.                 if (found==TRUE) {
  1101.                     if ((somethingSelected==FALSE) || (!EqualPt(oldCell,aCell))) {
  1102.                         LSetSelect(FALSE,oldCell,theList);  /* clear current selection */
  1103.                         LSetSelect(TRUE,aCell,theList);     /* set the new one */   
  1104.                         LAutoScroll(theList);
  1105.                     }
  1106.                 }
  1107.             break;
  1108.         }
  1109.     }
  1110. }
  1111.  
  1112.  
  1113. GetListSelections(aHandle)
  1114. Handle aHandle;
  1115. /* get the text of the selection made */
  1116. {
  1117.     char someSelect;
  1118.     Cell aCell;
  1119.     int stringLength,t,b,i;
  1120.     Str255 num,theText;
  1121.     long n,len;
  1122.     
  1123.     SetPt(&aCell, 0, 0);
  1124.     HLock(aHandle);
  1125.     strcpy(*aHandle,"");
  1126.     someSelect = LGetSelect(TRUE, &aCell, theList);
  1127.     while (someSelect==TRUE) {
  1128.         stringLength = 255;
  1129.         LGetCell(theText, &stringLength, aCell, theList);
  1130.         n = aCell.v+1;
  1131.         theText[stringLength] = 0;
  1132.         NumToString(n,num);
  1133.         PtoCstr((char *)num);
  1134.         strcat(num,",");
  1135.         strcat(num,theText);
  1136.         #if VERSION == XScrollBoxML
  1137.             strcat(num,"\15");              /* divide into lines */
  1138.         #else
  1139.             strcat(num,",");
  1140.         #endif
  1141.         len = GetHandleSize(aHandle);
  1142.         len = len + strlen(num);
  1143.         HUnlock(aHandle);
  1144.         SetHandleSize(aHandle,len);
  1145.         HLock(aHandle);
  1146.         strcat(*aHandle,num);
  1147.         aCell.v++;
  1148.         someSelect = LGetSelect(TRUE, &aCell, theList);
  1149.     }
  1150.     len = GetHandleSize(aHandle);
  1151.     if (len>0) {
  1152.         HUnlock(aHandle);
  1153.         SetHandleSize(aHandle,len-1);  /* clip off last comma */
  1154.         *(*aHandle+len-2) = 0;
  1155.         HLock(aHandle);
  1156.     }
  1157. }
  1158.  
  1159.  
  1160. /* clean up memory */
  1161.  
  1162. PrepareToExit()
  1163. {   
  1164.     if (theList != NULL) LDispose(theList);
  1165.     if (theListDialog != NULL) DisposDialog(theListDialog);
  1166. }
  1167.  
  1168. /* create scroll box, present it, return user's selection */
  1169.  
  1170. pascal void DoScrollBox(paramPtr)
  1171. XCmdBlockPtr    paramPtr;
  1172. {   
  1173.     Ptr thePrompt;
  1174.     Ptr theField;
  1175.     Ptr theUserButton;
  1176.     int status,i;
  1177.     Size len;
  1178.     
  1179.     resultHandle = NewHandle(2);
  1180.     if (paramPtr->paramCount < 3) {
  1181.         SetHandleSize(resultHandle,255);
  1182.         #if VERSION == XScrollBox
  1183.             strcpy(*resultHandle,"Not enough parameters in XScrollBox");
  1184.         #endif
  1185.         #if VERSION == XScrollBoxM
  1186.             strcpy(*resultHandle,"Not enough parameters in XScrollBoxM");
  1187.         #endif
  1188.         #if VERSION == XScrollBoxML
  1189.             strcpy(*resultHandle,"Not enough parameters in XScrollBoxML");
  1190.         #endif
  1191.         #if VERSION == XScrollBoxF
  1192.             strcpy(*resultHandle,"Not enough parameters in XScrollBoxF");
  1193.         #endif
  1194.     }   
  1195.     else {
  1196.         theCursor = GetCursor(watchCursor);
  1197.         SetCursor(*theCursor);
  1198.         for (i=0;i<paramPtr->paramCount;i++) {
  1199.             MoveHHi(paramPtr->params[i]);
  1200.             HLock(paramPtr->params[i]);
  1201.         }
  1202.         startHandle = paramPtr->params[0];
  1203.         startIsString = TRUE;
  1204.         
  1205.        strcpy(startString,*startHandle);
  1206.    #if (VERSION != XScrollBoxM) && (VERSION != XScrollBoxML)
  1207.        for (i=0;i<strlen(startString);i++) {
  1208.            if (!isalpha(startString[i])) {
  1209.                startIsString = FALSE;
  1210.                break;
  1211.            }
  1212.         }
  1213.  
  1214.        if (!startIsString) {
  1215.           CtoPstr((char *)*startHandle);  
  1216.           StringToNum(*startHandle,&theStartWith);
  1217.         }
  1218.         #endif
  1219.         
  1220.         thePrompt = *(paramPtr->params[1]);
  1221.         theField = *(paramPtr->params[2]);
  1222.         theUserButton = *(paramPtr->params[3]);
  1223.         if (GetHandleSize(paramPtr->params[3])>0)
  1224.             strcpy(userButton,theUserButton);
  1225.         else strcpy(userButton,"");
  1226.             
  1227.         #if VERSION == XScrollBoxF
  1228.             fontName[0] = 0;
  1229.             if (paramPtr->paramCount > 4) {
  1230.                 strcpy(fontName,*(paramPtr->params[4]));
  1231.             }
  1232.         #endif
  1233.         GetCardRect(&cardRect);
  1234.         status = SetupScrollBox(thePrompt,theField);
  1235.         InitCursor();
  1236.         if (status==1) {
  1237.             status = DoListDialog();
  1238.             if (status==1) GetListSelections(resultHandle);
  1239.             else if (status==2) {
  1240.                 SetHandleSize(resultHandle,1+strlen(userButton));
  1241.                 strcpy(*resultHandle,userButton);
  1242.             }
  1243.             else if (status==-1) {
  1244.                 strcpy(userButton,kCancelString);
  1245.                 SetHandleSize(resultHandle,1+strlen(userButton));
  1246.                 strcpy(*resultHandle,userButton);
  1247.             }
  1248.             else strcpy(*resultHandle,"");
  1249.         }
  1250.         else 
  1251.             #if VERSION == XScrollBox
  1252.                 strcpy(*resultHandle,
  1253.                     "Can't find dialog resource 1345 for XScrollBox XFCN");
  1254.             #endif
  1255.             #if VERSION == XScrollBoxM
  1256.                 strcpy(*resultHandle,
  1257.                     "Can't find dialog resource 1346 for XScrollBoxM XFCN");
  1258.             #endif
  1259.             #if VERSION == XScrollBoxF
  1260.                 strcpy(*resultHandle,
  1261.                     "Can't find dialog resource 1347 for XScrollBox XFCN");
  1262.             #endif
  1263.             #if VERSION == XScrollBoxML
  1264.                 strcpy(*resultHandle,
  1265.                     "Can't find dialog resource 1348 for XScrollBoxML XFCN");
  1266.             #endif
  1267.     }
  1268.     paramPtr->returnValue = resultHandle;
  1269.     for (i=0;i<paramPtr->paramCount;i++) HUnlock (paramPtr->params[i]);
  1270.     return;
  1271. }
  1272.  
  1273. /* this is the entry point for the XFCN */
  1274.  
  1275. pascal void main(paramPtr)
  1276. XCmdBlockPtr    paramPtr;
  1277. {
  1278.     RememberA0();
  1279.     SetUpA4();
  1280.     gParamPtr = paramPtr;
  1281.     DoScrollBox(paramPtr);  /* run the main event loop */   
  1282.     PrepareToExit();        /* tidy up */
  1283.     RestoreA4();            /* and this also */
  1284.     return;
  1285. }
  1286.